<template>
  <div class="wh-graph-editor">
    <!-- <editor-content ref="content" @loadedGraph="loadedGraph" /> -->
    <div class="wh-graph-editor-content" id="wh-graph-editor-container"></div>
    <editor-module @toggleSection="handleToggleSection" :graph="graph" />
    <editor-attr :current-cell="currentCellAttrs" @changeCell="handleChangeCell" @toggleSection="handleToggleSection" :grid="grid" @changeGrid="handleChangeGrid" />
    <editor-tools ref="editorTools" @on-click="handleClickTools" />
  </div>
</template>

<script>
import editorModule from './components/editorModule/index.vue'
import editorTools from './components/editorTools/index.vue'
import editorAttr from './components/editorAttribute/index.vue'
import { Graph, Shape } from '@antv/x6';
import { Stencil } from '@antv/x6-plugin-stencil'
import { Transform } from '@antv/x6-plugin-transform'
import { Selection } from '@antv/x6-plugin-selection'
import { Scroller } from '@antv/x6-plugin-scroller'
import { Snapline } from '@antv/x6-plugin-snapline'
import { Keyboard } from '@antv/x6-plugin-keyboard'
import { Clipboard } from '@antv/x6-plugin-clipboard'
import { History } from '@antv/x6-plugin-history'
import { MiniMap } from '@antv/x6-plugin-minimap'
import { Export } from '@antv/x6-plugin-export'


// import insertCss from 'insert-css'
export default {
  name: 'whGraphEditor',
  components: {
    editorModule,
    editorAttr,
    editorTools
  },
  data () {
    return {
      graph: null,
      grid: {
        visible: true,
        size: 10,
        type: 'fixedDot',
        args: {
          color: '#a0a0a0', // 网点颜色
          thickness: 2, // 网点大小
        },
      },
      currentCell: null,
      currentCellAttrs: null
    }
  },
  mounted() {
    this.initGraph()
  },
  methods: {
    initGraph () {
      this.graph = new Graph({
        container: document.getElementById('wh-graph-editor-container'),
        autoResize: true,
        background: {
          color: '#F2F7FA',
        },
        grid: this.grid,
        mousewheel: {
          enabled: true,
          zoomAtMousePosition: true,
          modifiers: 'ctrl',
          minScale: 0.5,
          maxScale: 3,
        },
        connecting: {
          router: 'manhattan',
          connector: {
            name: 'rounded',
            args: {
              radius: 8,
            },
          },
          anchor: 'center',
          connectionPoint: 'anchor',
          allowBlank: false,
          snap: {
            radius: 20,
          },
          createEdge() {
            return new Shape.Edge({
              attrs: {
                line: {
                  stroke: '#A2B1C3',
                  strokeWidth: 2,
                  targetMarker: {
                    name: 'block',
                    width: 12,
                    height: 8,
                  },
                },
              },
              zIndex: 0,
            })
          },
          validateConnection({ targetMagnet }) {
            return !!targetMagnet
          },
        },
        highlighting: {
          magnetAdsorbed: {
            name: 'stroke',
            args: {
              attrs: {
                fill: '#5F95FF',
                stroke: '#5F95FF',
              },
            },
          },
        }
      })
      this.graph.use(
        new Transform({
          resizing: true,
          rotating: true,
        }),
      )
      .use(
        new Selection({
          rubberband: true,
          showNodeSelectionBox: true,
        }),
      )
      .use(
        new Scroller({
          enabled: true,
          pageVisible: true,
          pageBreak: false,
          // pannable: false,
        })
      )
      .use(new Export())
      .use(new Snapline())
      .use(new Keyboard())
      .use(new Clipboard())
      .use(new History())
      .use(
        new MiniMap({
          container: document.getElementById('minimap'),
          width: 250,
          height: 200
        }),
      )
      // #region 快捷键与事件
      this.graph.bindKey(['meta+c', 'ctrl+c'], () => {
        const cells = this.graph.getSelectedCells()
        if (cells.length) {
          this.graph.copy(cells)
        }
        return false
      })
      this.graph.bindKey(['meta+x', 'ctrl+x'], () => {
        const cells = this.graph.getSelectedCells()
        if (cells.length) {
          this.graph.cut(cells)
        }
        return false
      })
      this.graph.bindKey(['meta+v', 'ctrl+v'], () => {
        if (!this.graph.isClipboardEmpty()) {
          const cells = this.graph.paste({ offset: 32 })
          this.graph.cleanSelection()
          this.graph.select(cells)
        }
        return false
      })

      // undo redo
      this.graph.bindKey(['meta+z', 'ctrl+z'], () => {
        if (this.graph.canUndo()) {
          this.graph.undo()
        }
        return false
      })
      this.graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
        if (this.graph.canRedo()) {
          this.graph.redo()
        }
        return false
      })

      // select all
      this.graph.bindKey(['meta+a', 'ctrl+a'], () => {
        const nodes = this.graph.getNodes()
        if (nodes) {
          this.graph.select(nodes)
        }
      })

      // delete
      this.graph.bindKey('backspace', () => {
        const cells = this.graph.getSelectedCells()
        if (cells.length) {
          this.graph.removeCells(cells)
        }
      })

      // zoom
      this.graph.bindKey(['ctrl+1', 'meta+1'], () => {
        const zoom = this.graph.zoom()
        if (zoom < 1.5) {
          this.graph.zoom(0.1)
        }
      })
      this.graph.bindKey(['ctrl+2', 'meta+2'], () => {
        const zoom = this.graph.zoom()
        if (zoom > 0.5) {
          this.graph.zoom(-0.1)
        }
      })

      // 控制连接桩显示/隐藏
      const showPorts = (ports, show) => {
        for (let i = 0, len = ports.length; i < len; i += 1) {
          ports[i].style.visibility = show ? 'visible' : 'hidden'
        }
      }
      // 鼠标进入节点
      this.graph.on('node:mouseenter', () => {
        const container = document.getElementById('wh-graph-editor-container')
        const ports = container.querySelectorAll(
          '.x6-port-body',
        )
        showPorts(ports, true)
      })
      // 鼠标离开节点
      this.graph.on('node:mouseleave', () => {
        const container = document.getElementById('wh-graph-editor-container')
        const ports = container.querySelectorAll(
          '.x6-port-body',
        )
        showPorts(ports, false)
      })

      // history改变
      this.graph.on('history:change', () => {
        this.$refs.editorTools.list[0][0].disabled = this.graph.canUndo()?0:1
        this.$refs.editorTools.list[0][1].disabled = this.graph.canRedo()?0:1
      })
      // 点击节点
      this.graph.on('node:click', ({cell, node}) => {
        console.log(cell);
        this.currentCell = cell
        this.currentCellAttrs = cell.getAttrs()

        const container = document.getElementById('wh-graph-editor-container')
        const ports = container.querySelectorAll(
          '.x6-port-body',
        )
        showPorts(ports, false)
      })
      // 点击边
      this.graph.on('edge:click', ({edge, view}) => {
        console.log(edge);
      //   this.currentCell = cell
      //   this.currentCellAttrs = cell.getAttrs()

        const container = document.getElementById('wh-graph-editor-container')
        const ports = container.querySelectorAll(
          '.x6-port-body',
        )
        showPorts(ports, false)
      })
      // 点击空白部分
      this.graph.on('blank:click', (e) => {
        this.currentCell = null
        this.currentCellAttrs = null
      })
    },
    // 点击上面的工具
    handleClickTools (item) {
      if (item.title === 'back') {
        this.graph.undo()
      } else if (item.title === 'next') {
        this.graph.redo()
      } else if (item.title === 'copy') {
        const cells = this.graph.getSelectedCells()
        if (cells.length) {
          this.graph.copy(cells)
        } else {
          this.$message.warning('请选择复制内容')
        }
        // this.graph.copy(this.currentCell)
      } else if (item.title === 'paste') {
        if (!this.graph.isClipboardEmpty()) {
          const cells = this.graph.paste({ offset: 32 })
          this.graph.cleanSelection()
          this.graph.select(cells)
        } else {
          this.$message.warning('暂无复制内容')
        }
      } else if (item.title === 'delete') {
        const cells = this.graph.getSelectedCells()
        if (cells.length) {
          this.graph.removeCells(cells)
        } else {
          this.$message.warning('请选择删除的对象')
        }
      } else if (item.title === 'export') {
        this.graph.exportPNG('流程图', {
          padding: 20
        })
      } else if (item.title === 'zoom-out') {
        const zoom = this.graph.zoom()
        if (zoom<1.5) {
          this.graph.zoom(0.1)
          this.$refs.editorTools.list[2][1].disabled = 0
        } else {
          this.$refs.editorTools.list[2][0].disabled = 1
        }
      } else if (item.title === 'zoom-in') {
        const zoom = this.graph.zoom()
        if (zoom > 0.5) {
          this.graph.zoom(-0.1)
          this.$refs.editorTools.list[2][0].disabled = 0
        } else {
          this.$refs.editorTools.list[2][1].disabled = 1
        }
      } else if (item.title === 'full-screen') {
        this.enterFullScreen()
      } else if (item.title === 'off-screen') {
        this.exitScreen()
      } else if (item.title === 'save') {
        console.log(this.graph.toJSON());
      } else if (item.title === 'minus-the-top') {
        if (this.currentCell) {
          this.currentCell.toFront({deep: true})
        } else {
          this.$message.warning('请选择要移动的对象')
        }
      } else if (item.title === 'minus-the-bottom') {
        if (this.currentCell) {
          this.currentCell.toBack({deep: true})
        } else {
          this.$message.warning('请选择要移动的对象')
        }
      }
    },
    // 切换左右工作区
    handleToggleSection (type) {
      this.$refs.editorTools.handleToggleSection(type)
    },
    // 修改grid
    handleChangeGrid (grid) {
      this.graph.drawGrid(grid)
    },
    // 修改cell
    handleChangeCell (cell) {
      this.currentCell.attr(cell)
    },
    // 进入全屏
    enterFullScreen () {
      let element = document.querySelector('body');
      console.log(element);
      if (element.requestFullscreen) {
          element.requestFullscreen().then(() => {
          }).catch((err) => {
              console.log(err);
          });
      } else if (element.webkitRequestFullScreen) {
          element.webkitRequestFullScreen().then(() => {
          }).catch((err) => {
              console.log(err);
          });
      } else if (element.mozRequestFullScreen) {
          element.mozRequestFullScreen().then(() => {
          }).catch((err) => {
              console.log(err);
          });
      } else if (element.msRequestFullscreen) {
          // IE11
          element.msRequestFullscreen().then(() => {
          }).catch((err) => {
              console.log(err);
          });
      }
    },
    // 退出全屏
    exitScreen(){
      if (document.exitFullscreen||document.documentElement.exitFullscreen) {
          document.exitFullscreen();
      } else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen();
      } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen();
      } else if (document.msExitFullscreen) {
          document.msExitFullscreen();
      }
    },
  }
}
</script>

<style scoped lang="scss">
  .wh-graph-editor {
    width: 100%;
    height: 100%;
    position: relative;
    &-content {
      width: 100%;
      height: 100%;
    }
  }
</style>
